﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace AgFractal
{
    public struct Complex
    {
        public double r;
        public double i;

        public Complex(double r, double i)
        {
            this.r = r;
            this.i = i;
        }

        public override string ToString()
        {
            return String.Format("({0},{1})", r, i);
        }
        public override int GetHashCode()
        {
            return ToString().GetHashCode();
        }

        public override bool Equals(object obj)
        {
            Complex? c = obj as Complex?;
            return c != null && c == this;
        }

        public static Complex operator +(Complex c1, Complex c2)
        {
            return new Complex(c1.r + c2.r, c1.i + c2.i);
        }

        public static Complex operator -(Complex c1, Complex c2)
        {
            return new Complex(c1.r - c2.r, c1.i - c2.i);
        }

        public static Complex operator -(Complex c1)
        {
            return new Complex(-c1.r, -c1.i);
        }


        public static Complex operator *(Complex c1, Complex c2)
        {
            return new Complex(c1.r * c2.r - c1.i * c2.i,
                c1.r * c2.i + c1.i * c2.r);
        }

        public static Complex operator /(Complex c1, Complex c2)
        {
            double d = c2.r * c2.r + c2.i * c2.i;
            return new Complex((c1.r * c2.r + c1.i * c2.i) / d,
                (c1.i * c2.r - c1.r * c2.i) / d);

        }

        public static bool operator ==(Complex c1, Complex c2)
        {
            return c1.r == c2.r && c1.i == c2.i;
        }

        public static bool operator !=(Complex c1, Complex c2)
        {
            return c1.r != c2.r || c1.i != c2.i;
        }


        public static implicit operator Complex(double d)
        {
            return new Complex(d, 0);
        }

        public double Abs()
        {
            return Math.Sqrt(r * r + i * i);
        }

        /// <summary>
        /// r * r + i * i
        /// </summary>
        /// <returns></returns>
        public double Abs2()
        {
            return r * r + i * i;
        }

        public double Angle()
        {
            return Math.Atan2(i, r);
        }

        public Complex Sqr()
        {
            return new Complex(r * r - i * i, 2 * r * i);
        }
        /// <summary>
        /// Conjuctive number (r,-i)
        /// </summary>
        /// <returns></returns>
        public Complex Conj()
        {
            return new Complex(r, -i);
        }

        public Complex Flip()
        {
            return new Complex(i, r);
        }

        public double Cabs()
        {
            return Math.Sqrt(r * r + i * i);
        }
    }
}
